/*
 * File:   main.c
 * Author:  Dominik H�ussler
 *          Ruben Schwarz
 *
 * Created on 2. M�rz 2011, 09:30
 *
 * �nderungen:
 * 2011/03/02   Real-Time-Clock implementiert
 *              UART2 f�r DEBUG-Zwecke implementiert
 */

//#include <p33Fxxxx.h>
#include  <p33FJ12MC202.h>
#include <uart.h>

#include <stdlib.h>
#include "sensor_typedefs.h"
#include "communication.h"
#include "hardware_settings.h"
//#include "mc.h"
#include "motorControl.h"

// Select Internal FRC at POR
_FOSCSEL(FNOSC_FRC);

// Enable Clock Switching and Configure
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF);


_FWDT(FWDTEN_OFF); // Watchdog Timer Enabled/disabled by user software

// Motor-Control Pin Control
_FPOR(HPOL_ON & LPOL_OFF);

// Globale Variablen
ESensorAct g_actSensor = NO_SENSOR_ACTIV;
ESystemState g_state = MOTORCONTROL_MODE;
int g_sens4 = 0;
int g_sens4_alarm = 0;
int g_motorSpeed = 0;

void __attribute__((__interrupt__, auto_psv)) _T2Interrupt(void) {
    IEC0bits.T2IE = 0;
    char input = getcUART1();

    if (!DataRdyUART1()) {
        switch (input) {
            case SENSOR_ADDR_0:
                break;
            case SENSOR_ADDR_1:
                break;
            case SENSOR_ADDR_2:
                sendSensorData(SENSOR_ADDR_2, DATA_REVOLUTION, g_motorSpeed, FALSE);
                break;
            case SENSOR_ADDR_3:
                sendSensorData(SENSOR_ADDR_3, DATA_VOLTAGE, 45, TRUE);
                break;
            case SENSOR_ADDR_4:
                sendSensorData(SENSOR_ADDR_4, DATA_VOLTAGE, g_sens4, g_sens4_alarm);
                break;
            case SENSOR_ADDR_5:
                sendSensorData(SENSOR_ADDR_5, DATA_CURRENT, 183, FALSE);
                break;
            case SENSOR_ADDR_6:
                break;
            case SENSOR_ADDR_7:
                break;
            case SENSOR_ADDR_8:
                break;
            case SENSOR_ADDR_9:
                break;
            case SENSOR_ADDR_10:
                break;
            case SENSOR_ADDR_11:
                break;
            case SENSOR_ADDR_12:
                break;
            case SENSOR_ADDR_13:
                break;
            case SENSOR_ADDR_14:
                break;
            case SENSOR_ADDR_15:
                break;
            case GOTO_CONFIG_MODE:
                g_state = CONFIGURATION_MODE;
            default: break;
                //TODO: auf Steuersignale reagieren (0x5A - Rücksetzen z.B.)
        }
    }
    //Unbenoetigte Zeichen aus UART-Lesepuffer löschen
    while (DataRdyUART1()) getcUART1();
    IFS0bits.T2IF = 0; //Clear Timer Interrupt Flag
} //ISR Timer2

void __attribute__((__interrupt__, auto_psv)) _U1RXInterrupt(void) {
    //reset timer2 and enable interrupt
    TMR2 = 0;
    IFS0bits.T2IF = 0;
    IEC0bits.T2IE = 1;
    //T2CONbits.TON = 1;
    IFS0bits.U1RXIF = 0; //Flag löschen
}

void __attribute__((__interrupt__, auto_psv)) _CNInterrupt(void) {
    //high
    if (PORTAbits.RA2)
        TMR1 = 0;
        //low
    else {
        if (TMR1 < SERVOTIMER_LOWER_LIMIT)
            g_motorSpeed = 0;
        else if (TMR1 > SERVOTIMER_UPPER_LIMIT)
            g_motorSpeed = 500;
        else
            g_motorSpeed = (5 * (TMR1 - SERVOTIMER_LOWER_LIMIT)) / (SERVOTIMER_DIFF);
    }

    IFS1bits.CNIF = 0; //Flag löschen
}

const unsigned int PWM_STATUS[] = {0x0210, 0x0204, 0x2004, 0x2001, 0x0801, 0x0810};


int main(void) {

    long long i = 0;
    int pwmState = 0;

    //Init Peripherie
    initClock();
    initUart();
    initTimer();
    initRemappablePins();
    initChangeNotification();
    //InitMC();
    initMc();

    //Loop forever
    while (1) {
        if(++pwmState > 5){
            pwmState = 0;
        }
        P1OVDCON = PWM_STATUS[pwmState];

        for(i=0; i<50000; i++);
    }

    return 0;
}
